﻿namespace EasyWeb.Web.UI
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Mvc;

    public class EWGridColumnBuilder<TModel>
    {
        public EWGridColumnBuilder(EWGrid<TModel> grid)
        {
            EWGuard.IsNotNull(grid, "grid");

            this.Component = grid;
            this.Columns = new List<EWGridColumn<TModel>>();
        }

        public EWGrid<TModel> Component { get; private set; }

        public IList<EWGridColumn<TModel>> Columns { get; private set; }

        public EWGridColumnBuilder<TModel> Bound<TValue>(
            Expression<Func<TModel, TValue>> expression,
            string header = null,
            bool canSort = false,
            Func<dynamic, object> format = null,
            string style = null)
        {
            EWGuard.IsNotNull(expression, "expression");

            var name = ExpressionHelper.GetExpressionText(expression);

            this.Columns.Add(new EWGridColumn<TModel>()
            {
                CanSort = canSort,
                ColumnName = name,
                Format = format,
                Header = header ?? ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary<TModel>()).DisplayName,
                Style = style
            });

            return this;
        }

        public EWGridColumnBuilder<TModel> Bound(
            string name,
            string header = null,
            bool canSort = false,
            Func<dynamic, object> format = null,
            string style = null)
        {
            EWGuard.IsNotNullOrEmpty(name, "name");

            this.Columns.Add(new EWGridColumn<TModel>()
            {
                CanSort = canSort,
                ColumnName = name,
                Format = format,
                Header = header ?? GetHeader(name),
                Style = style
            });

            return this;
        }

        public EWGridColumnBuilder<TModel> Template(
            string header,
            Func<dynamic, object> format,
            string style = null)
        {
            this.Columns.Add(new EWGridColumn<TModel>()
            {
                CanSort = false,
                ColumnName = null,
                Format = format,
                Header = header,
                Style = style
            });

            return this;
        }

        private static string GetHeader(string name)
        {
            var expression = EWHelpers.ExpressionHelpers.Lambda(typeof(TModel), name, false);
            var methodInfo = typeof(ModelMetadata)
                .GetTypeInfo()
                .GetMethod("FromLambdaExpression", BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy | BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static)
                .MakeGenericMethod(typeof(TModel), expression.Body.Type);
            var metadata = (ModelMetadata)methodInfo.Invoke(null, new object[] { expression, new ViewDataDictionary<TModel>() });
            return metadata.DisplayName;
        }
    }
}
